/********************************************************************************************************************************
 * 《C ++ Primer》第五版中文版，读书笔记：按照书中的的示例源码和每一个小章节的课后习题，自己动手写代码实现，作为联系和测试。
 * Date: 2024-03-25 09:46
 * Author: dimon.chen 
 * EMali: 1181302388@qq.com 
 * 
 * 章节: 第二章 变量和基本类型
 *       2.3.2 指针
 * 
 ********************************************************************************************************************************/


#include <iostream>

int main(int argc, char *argv[])
{

    ///
    /// 练习 2.3.2
    /// 2.18 编写代码分贝更改指针的值以及指针指向对象的值
    /// 
    ///

    int i1 = 0;
    //int *pVal = nullpointer;
    int *pVal = nullptr; //正确的空指针字面值常量是 nullptr

    //C++11 新标准刚引入的一种方法，使用字面值 nullptr 来初始化指针


    pVal = &i1;          // 更改指针的值，使其指向对象 i 
    *pVal = 1;          // 使用“解引用符 *”，修改指针指向对象的值

    std::cout << "i1=" << i1 << " *pVal=" << *pVal << std::endl;




    ///
    /// 练习 2.3.2 
    /// 2.19: 说明指针和引用的主要区别
    ///  

    /*
    * 1. 指针和引用都能间接访问另一个对象
    * 2. 指针和引用的主要区别
    *    指针本身是一个对象，而引用不是一个对象（是一个已存在对象的别名）。因为指针是一个对象，指针可以被赋值和拷贝，而且在指针的声明周期内它可以先后指向不同的对象，而引用一旦定义之后就不能重新绑定到另一个对象。
    *    指针无需在定义时赋初值，而引用在定义时必须初始化。 
    */


    ///
    /// 练习 2.3.2 
    /// 2.20: 请叙述下面这段代码的作用
    ///
#if 0
    int i = 42;             //定义int对象i
    int *pi = &i;           //声明并定义 int * 对象 pi，pi初始化执行对象i
    *pi = *pi * *pi;        //使用解引用符(*) 获取 pi指向的对象 i 的值，并执行算术运算，把算术运算结果写到 pi （解引用符）指向的对象。

    std::cout << "i=" << i << " *pi" << *pi << std::endl;
#endif

    ///
    /// 练习 2.3.2 
    /// 2.21: 请解释下属定义。在这些定义中有非法的么？如果有，为什么？
    ///
    int i = 0;
    //double *dp = &i;        //错误：指针的类型必须和它指向的类型严格匹配
    //int *ip = i;            //错误: 把 int 型变量直接赋值给指针是错误的，即使int变量的值恰好等于0也不行。
    int *p = &i;            //正确：int * 指针p，指向对象i


    return 0;
}